package com.hecate.user.service.impl;

import com.hecate.common.exception.HecateBusinessException;
import com.hecate.common.response.HecateResponse;
import com.hecate.common.response.HecateResponseCodeEnum;
import com.hecate.common.result.DefaultResult;
import com.hecate.common.result.IResult;
import com.hecate.user.api.req.dep.FindDepListBySupperDepReq;
import com.hecate.user.api.req.dep.FindDepTreeReq;
import com.hecate.user.api.req.dep.FindFirstLevelDepReq;
import com.hecate.user.api.req.dep.SaveDepReq;
import com.hecate.user.dto.dep.DepDTO;
import com.hecate.user.dto.dep.FindDepListBySupperDepDTO;
import com.hecate.user.dto.dep.FindFirstLevelDepDTO;
import com.hecate.user.dto.dep.SaveDepDTO;
import com.hecate.user.persistence.mapper.DepMapper;
import com.hecate.user.persistence.model.Dep;
import com.hecate.user.service.DepService;
import io.swagger.annotations.ApiModel;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 黄星星
 * @date 2020-06-13
 */
@ApiModel
@Service
public class DepServiceImpl implements DepService {

    @Autowired
    private DepMapper depMapper;

    @Override
    public HecateResponse<SaveDepDTO> saveDep(SaveDepReq saveDepReq) {
        String name = saveDepReq.getName();
        if (StringUtils.isEmpty(name)) {
            throw new HecateBusinessException("部门名称不能为空!");
        }
        String parentDepBid = saveDepReq.getParentDepBid();
        if (StringUtils.isEmpty(parentDepBid)) {
            throw new HecateBusinessException("父级部门不能为空!");
        }
        Long leve = saveDepReq.getLeve();
        if (null == leve) {
            throw new HecateBusinessException("部门级别不能为空!");
        }
        Dep dep = new Dep();
        BeanUtils.copyProperties(saveDepReq, dep);
        depMapper.save(dep);
        return null;
    }

    @Override
    public HecateResponse<FindFirstLevelDepDTO> findFirstLevelDep(FindFirstLevelDepReq findFirstLevelDepReq) {
        return null;
    }

    @Override
    public HecateResponse<FindDepListBySupperDepDTO> findDepListBySupperDep(FindDepListBySupperDepReq findDepListBySupperDepReq) {
        return null;
    }

    @Override
    public HecateResponse<Set<DepDTO>> findDepTree(FindDepTreeReq findDepTreeReq) {
        Long cid = findDepTreeReq.getCid();
        if (null == cid) {
            return HecateResponse.ERROR(HecateResponseCodeEnum.PARAM_IS_BLANK,"所属公司不能为空!");
        }

        IResult<Dep> firstLevelDepIResult = this.findFirstLevelDep(cid);
        if (!firstLevelDepIResult.isSuccess()) {
            return HecateResponse.ERROR(firstLevelDepIResult.getMsg());
        }
        Dep rootDep = firstLevelDepIResult.getData();
        List<Dep> allDepList = new ArrayList<>();
        allDepList.add(rootDep);
        IResult<List<Dep>> queryAllDepIResult = this.queryAllDep(cid, rootDep, allDepList);
        if(!queryAllDepIResult.isSuccess()){
            return HecateResponse.ERROR(queryAllDepIResult.getMsg());
        }

        allDepList = queryAllDepIResult.getData();

        if(!CollectionUtils.isEmpty(allDepList)){
            List<DepDTO> depDTOList = new ArrayList<>();
            BeanUtils.copyProperties(allDepList, depDTOList);

            IResult<Set<DepDTO>> depTreeIResult = this.buildDepTree(cid, depDTOList);
            if(!depTreeIResult.isSuccess()){
                return HecateResponse.ERROR(depTreeIResult.getMsg());
            }
            Set<DepDTO> depDtoSet = depTreeIResult.getData();
            return HecateResponse.SUCCESS(depDtoSet);
        }

        return HecateResponse.SUCCESS();
    }

    /**
     * 查看指定公司顶级部门信息
     *
     * @param cid
     * @return
     */
    public IResult<Dep> findFirstLevelDep(Long cid) {
        if (null == cid) {
            return DefaultResult.error("所属公司不能为空!");
        }
        Dep dep = depMapper.findFirstLevelDep(cid);
        if (null == dep) {
            return DefaultResult.error("该公司不存在顶级部门");
        }
        return DefaultResult.success(dep);
    }

    /**
     * 查询指定部门下的所有子部门
     *
     * @param cid
     * @param superDepBid
     * @return
     */
    public IResult<List<Dep>> findDepListBySupperDep(Long cid, String superDepBid) {
        if (null == cid) {
            return DefaultResult.error("所属公司不能为空!");
        }
        if (StringUtils.isEmpty(superDepBid)) {
            return DefaultResult.error("父级部门标识不能为空!");
        }
        List<Dep> depList = depMapper.findDepListBySupperDep(cid, superDepBid);
        return DefaultResult.success(depList);
    }

    /**
     * 查看指定公司的部门树结构
     *
     * @param cid
     * @return
     */
    public IResult<List<Dep>> queryAllDep(Long cid, Dep rootDep, List<Dep> allDepList) {

        if(null == rootDep){
            return DefaultResult.error("部门不能为空!");
        }
        if (null != rootDep) {

            String rootDepBid = rootDep.getBid();
            IResult<List<Dep>> childDepListBySupperDepIResult = this.findDepListBySupperDep(cid, rootDepBid);
            if (!childDepListBySupperDepIResult.isSuccess()) {
                return DefaultResult.error(childDepListBySupperDepIResult.getMsg());
            }
            List<Dep> depList = childDepListBySupperDepIResult.getData();
            if (!CollectionUtils.isEmpty(depList)) {
                allDepList.addAll(depList);
                for (Dep dep : depList) {
                    this.queryAllDep(cid, dep, allDepList);
                }
            }
        }
        return DefaultResult.success();
    }

    /**
     * 部门集合转换为部门树
     * @param cid
     * @param depList
     * @return
     */
    public IResult<Set<DepDTO>> buildDepTree(Long cid, List<DepDTO> depList){
        Set<DepDTO> trees = new LinkedHashSet<>();
        Set<DepDTO> depts = new LinkedHashSet<>();
        List<String> deptNames = depList.stream().map(DepDTO::getName).collect(Collectors.toList());
        boolean isChild;
        for (DepDTO depDTO : depList) {
            isChild = false;
            if (depDTO.getParentDepBid() == null) {
                trees.add(depDTO);
            }
            for (DepDTO it : depList) {
                if (it.getParentDepBid() != null && depDTO.getId().equals(it.getParentDepBid())) {
                    isChild = true;
                    if (depDTO.getChildDepList() == null) {
                        depDTO.setChildDepList(new ArrayList<>());
                    }
                    depDTO.getChildDepList().add(it);
                }
            }
            if (isChild) {
                depts.add(depDTO);
            } else if (depDTO.getParentDepBid() != null && !deptNames.contains(depMapper.findByBid(cid, depDTO.getParentDepBid()).getName())) {
                depts.add(depDTO);
            }
        }

        if (CollectionUtils.isEmpty(trees)) {
            trees = depts;
        }
        return DefaultResult.success(trees);
    }



}
